//
//  Transmitters.swift
//  ChainOfResponsibility
//
//  Created by LY on 2017/11/6.
//  Copyright © 2017年 DesignPatterns. All rights reserved.
//

import Foundation
class localTransmitter{
    func snedMessage(message:Message){
        print("Message to \(message.to) sent locally")
    }
}
class remoteTransmitter{
    func sendMessage(message:Message){
        print("Message to \(message.to) sent remotely")
    }
}
class Transmitter {
    var nextLink : Transmitter?
    required init(){}
    func sendMessage(_ message:Message){
        if nextLink != nil {
            nextLink!.sendMessage(message)
        }else{
            print("End of chain reached.Message not sent")
        }
    }
    func sendMessage(message:Message) -> Bool{
        if nextLink != nil {
            return nextLink!.sendMessage(message: message)
        }else{
            print("End of chain reached.Message not sent")
            return false
        }
    }
    func sendMessage(message: Message,handled : Bool = false) -> Bool{
        if nextLink != nil {
            return nextLink!.sendMessage(message:message,handled:handled)
        }else if !handled{
            print("End of chain reached. Message not sent")
        }
        return handled
    }
    fileprivate class func matchEmailSuffix(message:Message) -> Bool{
        if let index = message.from.index(of: "@"){
            return message.to.hasSuffix(String(message.from[index ..< message.from.endIndex]))
        }else{
            return false
        }
    }
    class func createChain() -> Transmitter?{
        let transmitterClasses:[Transmitter.Type] = [PriorityTransmitter.self,LocaleTransmitter.self,RemoteTransmitter.self]
        var link : Transmitter?
        for tClass in transmitterClasses.reversed(){
            let existingLink  = link
            link = tClass.init()
            link?.nextLink = existingLink
        }
        return link
    }
    class func createChain(localOnly:Bool) -> Transmitter?{
        let transmitterClass:[Transmitter.Type] = localOnly ? [PriorityTransmitter.self,LocaleTransmitter.self] : [PriorityTransmitter.self,LocaleTransmitter.self,RemoteTransmitter.self]
        var link : Transmitter?
        for tClass in transmitterClass{
            let existingLink = link
            link = tClass.init()
            link?.nextLink = existingLink
        }
        return link
    }
}
class LocaleTransmitter: Transmitter {
    override func sendMessage(_ message: Message) {
        if(Transmitter.matchEmailSuffix(message: message)){
            print("Message to \(message.to) sent locally")
        }else{
            super.sendMessage(message)
        }
    }
    override func sendMessage(message: Message) -> Bool {
        if(Transmitter.matchEmailSuffix(message: message)){
            print("Message to \(message.to) sent locally")
            return true
        }else{
            return super.sendMessage(message:message)
        }
    }
    override func sendMessage(message: Message, handled: Bool) -> Bool {
         var headlered = handled
        if(!handled&&Transmitter.matchEmailSuffix(message: message)){
            print("Message to \(message.to) sent locally")
          headlered = true
        }
        return super.sendMessage(message: message, handled: headlered)
    }
}
class RemoteTransmitter:Transmitter{
    override func sendMessage(_ message: Message) {
        if(!Transmitter.matchEmailSuffix(message: message)){
            print("Message to \(message.to) sent remotely")
        }else{
            super.sendMessage(message)
        }
    }
    override func sendMessage(message: Message) -> Bool {
        if(!Transmitter.matchEmailSuffix(message: message)){
            print("Message to \(message.to) sent remotely")
            return true
        }else{
            return super.sendMessage(message:message)
        }
    }
    override func sendMessage(message: Message, handled: Bool) -> Bool {
        var header = handled
        if(!header && !Transmitter.matchEmailSuffix(message: message)){
            print("Message to \(message.to) sent remotely")
            header = true
        }
        return super.sendMessage(message: message, handled: header)
    }
}
class PriorityTransmitter:Transmitter{
    var totalMessages = 0
    var handledMessage = 0
    override func sendMessage(_ message: Message) {
        if message.subject.contains("Priority") {
            print("Message to \(message.to) sent as priority")
        }else{
            super.sendMessage(message)
        }
    }
    override func sendMessage(message: Message) -> Bool {
        if message.subject.contains("Priority") {
            print("Message to \(message.to) sent as priority")
            return true
        }else{
            return super.sendMessage(message:message)
        }
    }
    override func sendMessage(message: Message, handled: Bool) -> Bool {
        totalMessages += 1
        var  header  = handled
        if message.subject.contains("Priority") {
            handledMessage += 1
            print("Message to \(message.to) sent as priority")
            print("Stats: Handled \(handledMessage) of \(totalMessages)")
            header = true
        }
        return super.sendMessage(message: message, handled: header)
    }
}
